import unittest
from dp.hashing import radix_encode, Hasher
import numpy as np
import time
from datetime import datetime
import matplotlib.pyplot as plt


class TestHashMethods(unittest.TestCase):

    # def test_hash(self):
    #     vector_size = 100000  # 100000
    #     dim = 20
    #     arrays = np.random.rand(vector_size, dim)
    #     start = time.time()
    #     hashed = [radix_encode(vec, 16) % 300 for vec in arrays]
    #     print(
    #         "average latency is ",
    #         (time.time() - start) / vector_size * 1e6,
    #         "microsecond. ",
    #     )
    #     # plt.hist(hashed, bins=100)
    #     # plt.xlabel("bin")
    #     # plt.ylabel("frequency")
    #     # plt.show()
    #     self.assertEqual(len(hashed), vector_size)

    def test_sql_hash(self):
        hasher = Hasher(model="glove-wiki-gigaword-50")

        # warm up
        for i in range(101):
            hashed = hasher.hash_query("select count(*) from foo")

        # run test
        points = [10, 100, 1000, 10000, 100000]

        times_simple = []
        start = time.time()
        for i in range(100001):
            hashed = hasher.hash_query("select count(*) from foo")
            if i in points:
                times_simple.append(time.time() - start)
                print(i)

        print(points)
        print(times_simple)

        times_p1 = []
        start = time.time()
        for i in range(100001):
            # hashed = hasher.hash_query("select count(*) from foo  ")
            hashed = hasher.hash_query(
                "select count(*) from foo  where density < 0.994"
            )
            if i in points:
                times_p1.append(time.time() - start)
                print(i)

        print(points)
        print(times_p1)

        times_p2 = []
        start = time.time()
        for i in range(100001):
            # hashed = hasher.hash_query("select count(*) from foo  ")
            hashed = hasher.hash_query(
                "select count(*) from foo  where density < 0.994 and color='red'"
            )
            if i in points:
                times_p2.append(time.time() - start)
                print(i)

        print(points)
        print(times_p2)

        plt.plot(points, times_simple, label="query", marker="o")
        plt.plot(points, times_p1, label="query+numerical", marker="v")
        plt.plot(points, times_p2, label="query+numerical+categorical", marker="1")
        plt.yscale("log")
        plt.xscale("log")
        plt.xlabel("Number of SQL queries")
        plt.ylabel("Time cost(s)")
        plt.legend()
        plt.show()
        self.assertEqual(len(times_simple), 6)


if __name__ == "__main__":
    unittest.main()
